home *** CD-ROM | disk | FTP | other *** search
- #include "rotmatrix.h"
-
- static Vector ZAxis(0,0,1);
-
- const int X = 0, Y = 1, Z = 2;
-
- // rotate_and_translate creates a transformation matrix
- // encapsulating a rotation followed by a translation.
- //
- // rot is the rotation vector (in degrees)
- // trans is the translation vector
- Matrix rotate_and_translate(
- const Vector &rot,
- const Vector &trans) {
-
- Matrix result;
-
- // Z rotation only if rx == ry == 0
- if (rot(X) == 0 && rot(Y) == 0) {
- result = rotate(ZAxis, rot(Z));
- } else {
- // theta is non-Z rotation angle
- float theta = sqrt(rot(X)*rot(X) + rot(Y)*rot(Y));
- Vector xyaxis(rot(X) / theta, rot(Y) / theta, 0);
-
- result = rotate(ZAxis, rot(Z)) * rotate(xyaxis, theta);
- }
-
- // Concatenate desired translation part
- result[X][3] = trans(X);
- result[Y][3] = trans(Y);
- result[Z][3] = trans(Z);
-
- return result;
- }
-
- // rotate(axis, angle) creates a matrix which rotates by
- // angle degrees around the given rotation axis.
- // The algorithm is taken more or less from Newman and Sproull, pp. 346-348.
- Matrix rotate(const Vector &a, float angle)
- {
- float v;
- Matrix R1, R1inv, R2, R2inv, R3;
-
- R1.identity();
- R2.identity();
- R3.identity();
-
- // R1 rotates a around z-axis to x-z plane
- v = sqrt(a(0)*a(0) + a(1)*a(1));
- if (v != 0) {
- R1[0][0] = R1[1][1] = a(0) / v;
- R1[1][0] = -(R1[0][1] = a(1) / v);
- }
- R1inv = R1;
- R1inv[1][0] = R1[0][1];
- R1inv[0][1] = R1[1][0];
-
- // R2 rotates a around y-axis to x-axis
- R2[0][0] = R2[2][2] = v;
- R2[2][0] = -(R2[0][2] = a(2));
- R2inv = R2;
- R2inv[2][0] = R2[0][2];
- R2inv[0][2] = R2[2][0];
-
- // R3 rotates around x-axis by angle
- angle = dtor(angle);
- R3[1][1] = R3[2][2] = cos(angle);
- R3[1][2] = -(R3[2][1] = sin(angle));
-
- // The composition works as follows:
- // R1 followed by R2 rotates the rotation axis into the X axis
- // R3 rotates by the desired angle around X
- // R2inv followed by R1inv rotates back to the rotation axis
- return R1inv * R2inv * R3 * R2 * R1;
- }
-